﻿
//////////////////////////////////////////////////////////////////////////////
//
// Copyright © 1998-2024 Glodon Company Limited.
//
// Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the “Software”),
// to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
//////////////////////////////////////////////////////////////////////////////

#include "ModelViewDlg.h"
#include "IFamily.h"
#include "IUiView.h"
#include "ICanvas.h"
#include "IDocument.h"
#include "DebugMode.h"
#include "GcmpModel.h"
#include "IModelView.h"
#include "ISelection.h"
#include "IUiManager.h"
#include "IGroupType.h"
#include "IMainWindow.h"
#include "IUiDocument.h"
#include "IApplication.h"
#include "IDockManager.h"
#include "IUiViewEvent.h"
#include "JournalUtils.h"
#include "IInstanceType.h"
#include "IActionManager.h"
#include "IDrawingLayout.h"
#include "IUndoRedoEvent.h"
#include "ICommandManager.h"
#include "IGenericElement.h"
#include "IUiDocumentEvent.h"
#include "IUiViewEventArgs.h"
#include "IRibbonContextualPage.h"
// #include "GcmpCommandNames.h"
#include "CommandParameters.h"
#include "IImportCADElement.h"
#include "ITransactionEvent.h"
#include "IUndoRedoEventArgs.h"
#include "IJournalCommandData.h"
#include "IUiViewEventHandler.h"
#include "IDrawingLayoutEvent.h"
#include "UiDocumentViewUtils.h"
#include "IUiDocumentEventArgs.h"
#include "ITransactionEventArgs.h"
#include "IUndoRedoEventHandler.h"
#include "IDrawingLayoutManager.h"
#include "IDrawingViewportEvent.h"
#include "IUiDocumentViewManager.h"
#include "IGraphicsNodeReference.h"
#include "IUiDocumentEventHandler.h"
#include "IDrawingLayoutEventArgs.h"
#include "IElementBasicInformation.h"
#include "IElementsChangeEventArgs.h"
#include "ITransactionEventHandler.h"
#include "IDrawingViewportEventArgs.h"
#include "IDrawingLayoutEventHandler.h"
#include "IElementsChangeEventHandler.h"
#include "IDrawingViewportEventHandler.h"
#include "GcmpBuiltInCategoryUniIdentities.h"

#include <QMenu>
#include <QTreeWidget>
#include <QMouseEvent>
#include "CommandIds.h"
#include "UiPlatformUtils.h"
#include "DocumentUtils.h"
#include "ModelViewUtils.h"
#include "ui_ModelViewDlg.h"
#include "UiLayoutManager.h"
#include "PropertyPalette.h"
#include "QTreeWidgetPaper.h"
#include "QFamilyTreeWidget.h"
#include "GmStyleSheetHelper.h"
#include "UiEventHandlerMacro.h"
// #include "QGroupObjectTreeWidget.h"
// #include "QImportedObjectTreeWidget.h"
#include "EnableCompileWarning_The_LAST_IncludeInCpp.h"

//来自GcmpCommandNames.h，平台的ID_OPEN_FILE和项目中的命名冲突
#ifndef ID_CMD_VIEWPORT_ACTIVATED
#define ID_CMD_VIEWPORT_ACTIVATED   L"gm.viewport.activated"
#endif
using namespace gcmp;
using namespace Sample;

// 是否将构件管理单独一个窗口
bool ShowFamilyInSeperatedTree = false;
// 是否将导入文件管理单独一个窗口
bool ShowImportedObjectsInSeparatedTree = false;
// 是否将组管理单独一个窗口
bool ShowGroupObjectsInSeparatedTree = false;
// 是否显示图纸管理
bool ShowTwoDimensionalDrawing = true;

namespace
{
    IUiDocumentViewManager* GetUiDocumentViewManager()
    {
        IUiDocumentViewManager* pUiDocViewMgr = IUiDocumentViewManager::Get();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiDocViewMgr, L"invalid pUiDocViewMgr",L"GDMP",L"2023-10-20");

        return pUiDocViewMgr;
    }

    IDock* GetDock(const std::wstring& modelViewDlgName)
    {
        IUiManager *pUiManager = IUiManager::Get();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pUiManager, L"pUiManager为空",L"GDMP",L"2023-10-20");

        IDockManager* pDockManager = pUiManager->GetDockManager();
        DBG_WARN_AND_RETURN_NULLPTR_UNLESS(pDockManager, L"pDockManager为空",L"GDMP",L"2023-10-20");

        return pDockManager->GetDock(modelViewDlgName);
    }
}

#pragma region 各种事务处理，通过文档，视图和图元事务初始化和更新资源管理器
namespace Sample
{
    //////////////////////////////////////////////////////////////////////////
    // ModelViewDlgUiDocumentEventHandler Ui文档事件处理
    class ModelViewDlgUiDocumentEventHandler : public gcmp::IUiDocumentEventHandler
    {
        DECLARE_UI_EVENT_HANDLER(ModelViewDlgUiDocumentEventHandler);

    private:
        // 只能被自己的静态函数构造
        ModelViewDlgUiDocumentEventHandler() :m_uiDocId(-1)
        {
        }
    public:
        virtual ~ModelViewDlgUiDocumentEventHandler()
        {
            UI_EVENT_HANDLER_SHOULD_CALL_ME_FIRSTLY_IN_DESTRUCTOR();
        }

    public:
        virtual void On(gcmp::IUiDocumentEventArgs* pArgs) override;

    private:
        void UIDocActivated(gcmp::IUiDocument* pUIDoc);
        void UIDocDeactivated(gcmp::IUiDocument* pUIDoc);

        void Register();

    private:
        int  m_uiDocId;
    };

    IMPLEMENT_UI_EVENT_HANDLER(ModelViewDlgUiDocumentEventHandler);

    void ModelViewDlgUiDocumentEventHandler::Register()
    {
        IUiDocumentViewManager* pUiDocViewMgr = GetUiDocumentViewManager();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocViewMgr, L"invalid pUiDocViewMgr",L"GDMP",L"2023-10-20");

        IUiDocumentEvent *pUiDocEvent = pUiDocViewMgr->GetUiDocumentEvent();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocEvent, L"invalid pUiDocEvent",L"GDMP",L"2023-10-20");

        pUiDocEvent->Add(this);
    }

    void ModelViewDlgUiDocumentEventHandler::On(gcmp::IUiDocumentEventArgs* pArgs)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(pArgs, L"pArgs为空。",L"GDMP",L"2023-10-20");

        UiDocumentEventType uiEventType = pArgs->GetType();
        switch (uiEventType)
        {
            case UiDocumentEventType::UiDocumentActivated:
            {
                this->UIDocActivated(pArgs->GetUiDocument());
                break;
            }

            case UiDocumentEventType::UiDocumentDeactivated:
            {
                this->UIDocDeactivated(pArgs->GetUiDocument());
                break;
            }

            case UiDocumentEventType::UiDocumentClosed:
            {
                IUiDocumentViewManager* pUiDocViewMgr = GetUiDocumentViewManager();
                DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocViewMgr, L"pUiDocViewMgr为空。",L"GDMP",L"2023-10-20");

                //由于pUiDocMgr的事件发送早与文档关闭，allUiDoc最小为1
                if (pUiDocViewMgr->GetAllUiDocuments().size() <= 1)
                {
                    IDock* pModelViewDock = GetDock(DOCK_PAGE_NAME_VIEW_MANAGEMENT);
                    if (pModelViewDock)
                    {
                        pModelViewDock->Hide();
                    }
                }

                break;
            }
        }
    }

    void ModelViewDlgUiDocumentEventHandler::UIDocActivated(IUiDocument* pUIDoc)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(pUIDoc != nullptr, L"pUIDoc不能为空",L"GDMP",L"2023-10-20");
        m_uiDocId = pUIDoc->GetId();

        ModelViewDlg* pModelViewDlg = dynamic_cast<ModelViewDlg*>(IModelViewDlg::Get(DOCK_PAGE_NAME_VIEW_MANAGEMENT));

        DBG_WARN_AND_RETURN_VOID_UNLESS(pModelViewDlg != nullptr, L"应该有pModelViewDlg",L"GDMP",L"2023-10-20");

        pModelViewDlg->Init(pUIDoc);

        pModelViewDlg->AttachEventHandler(pUIDoc);
    }

    void ModelViewDlgUiDocumentEventHandler::UIDocDeactivated(IUiDocument* pUIDoc)
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(pUIDoc != nullptr, L"pUIDoc不能为空",L"GDMP",L"2023-10-20");
        if (m_uiDocId != pUIDoc->GetId())
            return;

        ModelViewDlg* pModelViewDlg = dynamic_cast<ModelViewDlg*>(IModelViewDlg::Get(DOCK_PAGE_NAME_VIEW_MANAGEMENT));

        DBG_WARN_AND_RETURN_VOID_UNLESS(pModelViewDlg != nullptr, L"应该有pModelViewDlg",L"GDMP",L"2023-10-20");

        pModelViewDlg->DetachEventHandler(pUIDoc);

        //pLayoutManager->Clear();
        m_uiDocId = -1;
    }

    //////////////////////////////////////////////////////////////////////////
    // ModelViewDlgUiEventHandler Ui事件处理
    class ModelViewDlgUiViewEventHandler :public gcmp::IUiViewEventHandler
    {
        DECLARE_UI_EVENT_HANDLER(ModelViewDlgUiViewEventHandler);

    private:
        // 只能被自己的静态函数构造
        ModelViewDlgUiViewEventHandler()
        {
        }
    public:
        virtual ~ModelViewDlgUiViewEventHandler()
        {
            UI_EVENT_HANDLER_SHOULD_CALL_ME_FIRSTLY_IN_DESTRUCTOR();
        }

    private:
        void Register()
        {
            IUiDocumentViewManager* pUiDocViewMgr = GetUiDocumentViewManager();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocViewMgr, L"pUiDocViewMgr为空。",L"GDMP",L"2023-10-20");

            IUiViewEvent* pUiViewEvent = pUiDocViewMgr->GetUiViewEvent();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pUiViewEvent, L"invalid pUiViewEvent",L"GDMP",L"2023-10-20");

            pUiViewEvent->Add(this);
        }

    public:
        virtual void On(IUiViewEventArgs* pArgs) override
        {
            DBG_WARN_AND_RETURN_VOID_UNLESS(pArgs, L"pArgs为空。",L"GDMP",L"2023-10-20");

            if (UiViewEventType::UiViewActivated == pArgs->GetType())
            {
                ModelViewDlg* pModelViewDlg = dynamic_cast<ModelViewDlg*>(IModelViewDlg::Get(DOCK_PAGE_NAME_VIEW_MANAGEMENT));

                DBG_WARN_AND_RETURN_VOID_UNLESS(pModelViewDlg != nullptr, L"应该有pModelViewDlg",L"GDMP",L"2023-10-20");

                pModelViewDlg->Init(pArgs->GetUiView()->GetUiDocument());
            }
        }
    };

    IMPLEMENT_UI_EVENT_HANDLER(ModelViewDlgUiViewEventHandler);

    //////////////////////////////////////////////////////////////////////////
    // ModelViewDlgUndoRedoEventHandler undoRedo事件处理
    class ModelViewDlgUndoRedoEventHandler :public gcmp::IUndoRedoEventHandler
    {
    public:
        ModelViewDlgUndoRedoEventHandler(ModelViewDlg* pModelViewDlg)
            :m_pModelViewDlg(pModelViewDlg)
        {
            DBG_WARN_UNLESS(pModelViewDlg != nullptr, L"pModelViewDlg不能为空",L"GDMP",L"2023-10-20");
        }
    private:
        ModelViewDlgUndoRedoEventHandler() {}

        void On(IUndoRedoEventArgs* pArgs) override

        {
            if (!pArgs)
                return;

            UndoRedoEventType eventType = pArgs->GetType();
            switch (eventType)
            {
            case PostUndo:
            case PostRedo:
            {
                if (m_pModelViewDlg->m_isNeedUpdate && m_pModelViewDlg->isVisible())
                {
                    m_pModelViewDlg->Refresh();
                }
                break;
            }
            default:
                break;
            }
        }

    private:
        ModelViewDlg* m_pModelViewDlg;
    };

    //////////////////////////////////////////////////////////////////////////
    // ModelViewDlgTransactionEventHandler 事件处理
    class ModelViewDlgTransactionEventHandler :public gcmp::ITransactionEventHandler
    {
    public:
        ModelViewDlgTransactionEventHandler(ModelViewDlg* pModelViewDlg)
            :m_pModelViewDlg(pModelViewDlg)
        {
            DBG_WARN_UNLESS(pModelViewDlg != nullptr, L"pModelViewDlg不能为空",L"GDMP",L"2023-10-20");
        }
    private:
        ModelViewDlgTransactionEventHandler() {}

        void On(ITransactionEventArgs* pArgs) override
        {
            if (!pArgs)
                return;

            TransactionEventType eventType = pArgs->GetType();
            switch (eventType)
            {
            case gcmp::PostCommit:
            case gcmp::PostRollBack:
            {
                if (m_pModelViewDlg->m_isNeedUpdate && m_pModelViewDlg->isVisible())
                {
                    m_pModelViewDlg->Refresh();
                }
                break;
            }
            default:
                break;
            }
        }
    private:
        ModelViewDlg* m_pModelViewDlg;
    };

    //////////////////////////////////////////////////////////////////////////
    // db文档Element 修改事件处理
    class ModelViewDlgElementChangeEventHandler : public gcmp::IElementsChangeEventHandler
    {
    public:
        ModelViewDlgElementChangeEventHandler(ModelViewDlg* pModelViewDlg)
            :m_pModelViewDlg(pModelViewDlg)
        {
            DBG_WARN_UNLESS(pModelViewDlg != nullptr, L"pModelViewDlg不能为空",L"GDMP",L"2023-10-20");
        }
    private:
        ModelViewDlgElementChangeEventHandler() {}

        void On(IElementsChangeEventArgs* pArgs) override
        {
            if (!pArgs)
                return;

            std::vector<const IElement*> pElements = pArgs->GetElements();
            if (pElements.empty())
            {
                return;
            }

            if (m_pModelViewDlg->m_isNeedUpdate)
            {
                return;
            }

            IUiDocument* pUIDoc = GetUiDocumentViewManager()->GetCurrentUiDocument();
            FOR_EACH(pElement, pElements)
            {
                if (m_pModelViewDlg->m_isNeedUpdate)
                {
                    break;
                }
                if (pUIDoc && pUIDoc->GetDbDocument() == pElement->GetDocument())
                {
                    if (const IModelView* pModelView = quick_cast<const IModelView>(pElement))
                    {
                        m_pModelViewDlg->m_isNeedUpdate = true;
                    }
                    else if (const IFamily* pFamily = quick_cast<const IFamily>(pElement))
                    {
                        m_pModelViewDlg->m_isNeedUpdate = true;
                    }
                    else if (const IInstanceType* pInstancetype = dynamic_cast<const IInstanceType*>(pElement))
                    {
                        m_pModelViewDlg->m_isNeedUpdate = true;
                    }
                    else if (const IImportCADElement* pImportCADElement =
                        quick_cast<const IImportCADElement> (pElement))
                    {
                        m_pModelViewDlg->m_isNeedUpdate = true;
                    }
                    else if (const IGroupType* pGroupType = quick_cast<const IGroupType>(pElement))
                    {
                        m_pModelViewDlg->m_isNeedUpdate = true;
                    }
                }
            }
        }

    private:
        ModelViewDlg* m_pModelViewDlg;
    };

    class UpdateUiViewLayoutEventHandler :public gcmp::IDrawingLayoutEventHandler
    {
    public:
        UpdateUiViewLayoutEventHandler(ModelViewDlg* pModelViewDlg)
            :m_pModelViewDlg(pModelViewDlg)
        {
            DBG_WARN_UNLESS(pModelViewDlg, L"pModelViewDlg为空",L"GDMP",L"2023-10-20");
        }

        ~UpdateUiViewLayoutEventHandler()
        {
        }

        virtual void On(IDrawingLayoutEventArgs* pArgs) override
        {
            if (pArgs == nullptr)
                return;

            if (pArgs->GetType() != DrawingLayoutEventType::Created && pArgs->GetType() != DrawingLayoutEventType::PreDeletion)
            {
                return;
            }

            IUiDocumentViewManager* pDocViewMgr = GetUiDocumentViewManager();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pDocViewMgr, L"pDocViewMgr为空",L"GDMP",L"2023-10-20");
            IDocument* pDoc = pDocViewMgr->GetCurrentUiDocument()->GetDbDocument();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc为空",L"GDMP",L"2023-10-20");
            if (pDoc != pArgs->GetDocument())
                return;

            if (const IDrawingLayoutEvent* pLayoutEvent = dynamic_cast<const IDrawingLayoutEvent*>(pArgs->GetEvent()))
            {
                QTreeWidgetItem* pRootPaper = m_pModelViewDlg->GetRootPaperItem();
                DBG_WARN_AND_RETURN_VOID_UNLESS(pRootPaper, L"pRootPaper为空",L"GDMP",L"2023-10-20");

                if (pArgs->GetType() == DrawingLayoutEventType::Created)          // 图纸创建
                {
                    IGenericElement* pGenericElem = Sample::DocumentUtils::GetElement<IGenericElement>(pDoc, pArgs->GetLayoutId());
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pGenericElem, L"pGenericElem为空",L"GDMP",L"2023-10-20");
                    IDrawingLayout* pLayout = quick_cast<IDrawingLayout>(pGenericElem->GetExternalObject());
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pLayout, L"pLayout为空",L"GDMP",L"2023-10-20");
                    if (QTreeWidgetPaper::FindChildWidgetItem(pLayout->GetName()) == nullptr)
                    {
                        QTreeWidgetPaper::UpdatePaperItems(pRootPaper, pDoc);
                        return;
                    }
                    else
                        return;
                }
                else if (pArgs->GetType() == DrawingLayoutEventType::PreDeletion) // 图纸删除
                {
                    IGenericElement* pGenericElem = Sample::DocumentUtils::GetElement<IGenericElement>(pDoc, pArgs->GetLayoutId());
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pGenericElem, L"pGenericElem为空",L"GDMP",L"2023-10-20");
                    IDrawingLayout* pLayout = quick_cast<IDrawingLayout>(pGenericElem->GetExternalObject());
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pLayout, L"pLayout为空",L"GDMP",L"2023-10-20");
                    if (QTreeWidgetPaper::FindChildWidgetItem(pLayout->GetName()))
                    {
                        QTreeWidgetPaper::UpdatePaperItems(pRootPaper, pDoc);
                        return;
                    }
                    else
                        return;
                }
            }
        }
    private:
        ModelViewDlg* m_pModelViewDlg;
    };

    class UpdateUiViewViewportEventHandler :public gcmp::IDrawingViewportEventHandler
    {
    public:
        UpdateUiViewViewportEventHandler(ModelViewDlg* pModelViewDlg)
            :m_pModelViewDlg(pModelViewDlg)
        {
            DBG_WARN_UNLESS(pModelViewDlg, L"pModelViewDlg为空",L"GDMP",L"2023-10-20");
        }

        ~UpdateUiViewViewportEventHandler()
        {
        }

        virtual void On(IDrawingViewportEventArgs* pArgs) override
        {
            if (pArgs == nullptr)
                return;

            if (pArgs->GetType() != DrawingViewportEventType::Created && pArgs->GetType() != DrawingViewportEventType::PreDelete)
            {
                return;
            }

            IUiDocumentViewManager* pDocViewMgr = GetUiDocumentViewManager();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pDocViewMgr, L"pDocViewMgr为空",L"GDMP",L"2023-10-20");
            IDocument* pDoc = pDocViewMgr->GetCurrentUiDocument()->GetDbDocument();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc为空",L"GDMP",L"2023-10-20");
            if (pDoc != pArgs->GetDocument())
                return;

            if (const IDrawingViewportEvent* pViewportEvent = dynamic_cast<const IDrawingViewportEvent*>(pArgs->GetEvent()))
            {
                QTreeWidgetItem* pRootPaper = m_pModelViewDlg->GetRootPaperItem();
                DBG_WARN_AND_RETURN_VOID_UNLESS(pRootPaper, L"pRootPaper为空",L"GDMP",L"2023-10-20");
                QTreeWidgetPaper::UpdatePaperItems(pRootPaper, pDoc);
            }
        }
    private:
        ModelViewDlg* m_pModelViewDlg;
    };
}
#pragma endregion 各种事务处理，通过文档，视图和图元事务初始化和更新资源管理器

Sample::ModelViewDlg::ModelViewDlg(const ModelViewDlgInput& input)
    : m_uiDocID(0)
    , m_isNeedUpdate(false)
    , m_pElementChangeEventHandler(nullptr)
    , m_pFamilyTree(nullptr)
    , m_bShowFamilyManagementMenuItem(input.IsShowFamilyManagementMenuItem)
    , m_ui(NEW_AS_OWNER_PTR(Ui::ModelViewDlg))
{
    m_ui->setupUi(this);

    std::wstring styleSheetStr = Sample::GmStyleSheetHelper::Instance()->GetCurrentStyleData();
    setStyleSheet(QString::fromStdWString(styleSheetStr));

    m_treeMenu = NEW_AS_QT_CHILD(QMenu, this);
    m_treeMenu->setObjectName("TreeMenu");

    if (m_ui->modelViewTree)
    {
        m_ui->modelViewTree->clear();
        m_ui->modelViewTree->header()->setVisible(false);
        m_ui->modelViewTree->setFocusPolicy(Qt::ClickFocus);
        m_ui->modelViewTree->setSelectionMode(QAbstractItemView::ExtendedSelection);
        connect(m_ui->modelViewTree, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(OnModelViewTreeItemDoubleClicked(QTreeWidgetItem*, int)));
    }

    // 初始化UiDoc事件处理
    ModelViewDlgUiDocumentEventHandler* pUiDocEventHandle = ModelViewDlgUiDocumentEventHandler::GetInstance();

    // 初始化UiView事件处理
    ModelViewDlgUiViewEventHandler* pUiViewEventHanle = ModelViewDlgUiViewEventHandler::GetInstance();

    // 初始化ElementChange事件处理
    m_pElementChangeEventHandler = NEW_AS_OWNER_PTR(ModelViewDlgElementChangeEventHandler, this);

    // 初始化UndoRedo事件处理
    m_pUndoRedoEventHandler = NEW_AS_OWNER_PTR(ModelViewDlgUndoRedoEventHandler, this);

    // 初始化Transaction事件处理
    m_pTransactionEventHandler = NEW_AS_OWNER_PTR(ModelViewDlgTransactionEventHandler, this);

    m_opUiLayoutManager = NEW_AS_OWNER_PTR(UiLayoutManager, this);

    //初始化图纸树
    // InitPaperTree();
    m_opLayoutEventHandler = NEW_AS_OWNER_PTR(UpdateUiViewLayoutEventHandler, this);
    IDrawingLayoutManager::GetLayoutEvent()->Add(m_opLayoutEventHandler.get());
    m_opViewportEventHandler = NEW_AS_OWNER_PTR(UpdateUiViewViewportEventHandler, this);
    IDrawingLayout::GetViewportEvent()->Add(m_opViewportEventHandler.get());

    // 初始化族树
    InitFamilyTree();
    InitImportedObjectTree();
    InitGroupObjectTree();
}

Sample::ModelViewDlg::~ModelViewDlg()
{
}

void Sample::ModelViewDlg::keyPressEvent(QKeyEvent *event)
{
    switch (event->key())
    {
    case Qt::Key_Escape: //绕过QDialogESC键默认关闭对话框处理,同时保持消息路由
        event->ignore();
        QWidget::keyPressEvent(event);
        break;
    case Qt::Key_Delete:
        if (m_ui->modelViewTree->currentItem()->data(0, PAPER_USER_DATA_ROLE).toString().toStdWString() == L"Drawing Layout"
            || m_ui->modelViewTree->currentItem()->data(0, PAPER_USER_DATA_ROLE).toString().toStdWString() == L"Drawing Viewport")
        {
            RemoveSelectedPaperOrViewPort();
        }
        else
        {
            RemoveSelectedModelView();
        }
        break;
    default:
        QDialog::keyPressEvent(event);
    }
}

void Sample::ModelViewDlg::leaveEvent(QEvent *)
{
    //将键盘事件路由到父窗口
   setFocus();

}

void Sample::ModelViewDlg::showEvent(QShowEvent *event)
{
    Refresh();
}

void Sample::ModelViewDlg::contextMenuEvent(QContextMenuEvent*event)
{
    QPoint mousePosInTree = event->pos() - m_ui->modelViewTree->pos();
    QTreeWidgetItem *item = m_ui->modelViewTree->itemAt(mousePosInTree);
    if (item != nullptr)
    {
        if (!item->isSelected())
        {
            m_ui->modelViewTree->clearSelection();
            m_ui->modelViewTree->setCurrentItem(item);
            item->setSelected(true);
        }
        if (item->data(0, FAMILY_USER_DATA_ROLE).isValid())
        {
            if (m_treeMenu != nullptr)
            {
                QList<QTreeWidgetItem*> selectedItem = m_ui->modelViewTree->selectedItems();
                UpdateFamilyTreeItemContextMenu(selectedItem);
            }
        }
        else if (item->data(0, IMPORT_USER_DATA_ROLE).isValid())
        {
            if (m_treeMenu != nullptr)
            {
                QList<QTreeWidgetItem*> selectedItem = m_ui->modelViewTree->selectedItems();
                UpdateImportedObjectTreeItemContextMenu(selectedItem);
            }
        }
        else if (item->data(0, GROUP_USER_DATA_ROLE).isValid())
        {
            if (m_treeMenu != nullptr)
            {
                QList<QTreeWidgetItem*> selectedItem = m_ui->modelViewTree->selectedItems();
                UpdateGroupObjectTreeItemContextMenu(selectedItem);
            }
        }
        else if (item->data(0, MODEL_VIEW_USER_DATA_ROLE).isValid())
        {
            if (m_treeMenu != nullptr)
            {
                m_treeMenu->clear();
                /*/ TODO：相关命令后续实现
                QAction* pRemoveModelViewAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"删除")));
                connect(pRemoveModelViewAction, SIGNAL(triggered(bool)), this, SLOT(RemoveSelectedModelView()));
                */
            }
        }
        else if (item->data(0, PAPER_USER_DATA_ROLE).isValid())
        {
            if (m_treeMenu != nullptr)
            {
                m_treeMenu->clear();
                /*/ TODO：相关命令后续实现
                QAction* pRemovePaperorViewPortAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"删除")));
                DBG_WARN_AND_RETURN_VOID_UNLESS(pRemovePaperorViewPortAction, L"pRemovePaperorViewPortAction为空",L"GDMP",L"2023-10-20");
                connect(pRemovePaperorViewPortAction, SIGNAL(triggered(bool)), this, SLOT(RemoveSelectedPaperOrViewPort()));

                if (item->data(0, PAPER_USER_DATA_ROLE).toString().toStdWString() == L"Drawing Viewport")
                {
                    QTreeWidgetItem* layoutItem = item->parent();
                    DBG_WARN_AND_RETURN_VOID_UNLESS(layoutItem, L"视口item对应的图纸item为空",L"GDMP",L"2023-10-20");
                    std::wstring layoutName = layoutItem->text(0).toStdWString();
                    IDocument* pDoc = UiDocumentViewUtils::GetCurrentDocument();
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc为空",L"GDMP",L"2023-10-20");
                    std::wstring errorMsg = L"";
                    IDrawingLayoutManager* pLayoutManager = IDrawingLayoutManager::Get(pDoc, &errorMsg);
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pLayoutManager, L"IDrawingLayoutManager::Get为空",L"GDMP",L"2023-10-20");
                    IDrawingLayout* pLayout = pLayoutManager->GetLayout(layoutName);
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pLayout, L"pLayout为空",L"GDMP",L"2023-10-20");
                    IDrawingViewport* pViewport = pLayout->GetViewport(item->text(0).toStdWString());
                    DBG_WARN_AND_RETURN_VOID_UNLESS(pViewport, L"pViewport为空",L"GDMP",L"2023-10-20");
                    if (pViewport->IsEnableActive() && pViewport->IsActive())
                    {
                        QAction* pViewPortDeactivateAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"视口反激活")));
                        DBG_WARN_AND_RETURN_VOID_UNLESS(pViewPortDeactivateAction, L"pViewPortDeactivateAction为空",L"GDMP",L"2023-10-20");
                        connect(pViewPortDeactivateAction, SIGNAL(triggered(bool)), this, SLOT(ViewportDeactivate()));
                    }
                }
                */
            }
        }
        else if (item->data(0, Qt::UserRole).isValid())
        {
            if (m_treeMenu != nullptr)
            {
                m_treeMenu->clear();
                QAction* pAddModelViewAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"创建/打开")));
                QVariant viewType = item->data(1, Qt::UserRole);
                if (viewType == QString::fromStdWString(View3DViewType))
                {
                    connect(pAddModelViewAction, SIGNAL(triggered(bool)), this, SLOT(CreateOpen3DView()));
                }
                else if (viewType == QString::fromStdWString(PlanViewType))
                {
                    connect(pAddModelViewAction, SIGNAL(triggered(bool)), this, SLOT(CreateOpenPlanView()));
                }
                else if (viewType == QString::fromStdWString(SectionViewType))
                {
                    connect(pAddModelViewAction, SIGNAL(triggered(bool)), this, SLOT(CreateOpenSectionView()));
                }
                else if (viewType == QString::fromStdWString(DrawingLayoutViewType))
                {
                    connect(pAddModelViewAction, SIGNAL(triggered(bool)), this, SLOT(CreateLayout()));
                }
            }
        }
        else
            return;
        if (m_treeMenu)
        {
            if (!m_treeMenu->isEmpty())
            {
                m_treeMenu->exec(QCursor::pos()); //在当前鼠标位置显示
            }
        }
    }

    QDialog::contextMenuEvent(event);
}

void Sample::ModelViewDlg::UpdateFamilyTreeItemContextMenu(const QList<QTreeWidgetItem*>& selectedItem)
{
    m_treeMenu->clear();

    if (selectedItem.size() == 1)
    {
        // 单选
        int nodeType = selectedItem[0]->data(0, FAMILY_USER_DATA_ROLE).toInt();
        if (nodeType == TWNT_FAMILY)
        {
            if (m_bShowFamilyManagementMenuItem)
            {
                /*/ TODO：相关命令后续实现*/
                /*
                QAction* pRenameFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"重命名")));
                connect(pRenameFamilyAction, SIGNAL(triggered(bool)), this, SLOT(RenameFamily()));

                QAction* pEditFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"编辑")));
                connect(pEditFamilyAction, SIGNAL(triggered(bool)), this, SLOT(EditFamily()));

                QAction* pSaveAsFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"另存为")));
                connect(pSaveAsFamilyAction, SIGNAL(triggered(bool)), this, SLOT(SaveAsFamily()));
                */
                QAction* pRemoveFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"删除")));
                connect(pRemoveFamilyAction, SIGNAL(triggered(bool)), this, SLOT(RemoveFamily()));
            }
        }
        else if (nodeType == TWNT_FAMILYTYPE)
        {
            /*/ TODO：相关命令后续实现
            QAction* pCreateFamilyInstance = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"创建实例")));
            connect(pCreateFamilyInstance, SIGNAL(triggered(bool)), this, SLOT(CreateFamilyInstance()));
            */
        }
        else if (nodeType == TWNT_FAMILY_ROOT)
        {
            /*/ TODO：相关命令后续实现  
            if (m_bShowFamilyManagementMenuItem)
            {
                QAction* pLoadFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"载入...")));
                connect(pLoadFamilyAction, SIGNAL(triggered(bool)), this, SLOT(LoadFamily()));

                QAction* pLoadSubFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"载入子构件...")));
                if (pLoadSubFamilyAction)
                {
                    connect(pLoadSubFamilyAction, SIGNAL(triggered(bool)), this, SLOT(LoadSubFamily()));
                }
            }
            */
        }
    }
    else if (selectedItem.size() > 1)
    {
        // 多选
        int nodeType = 0;
        for (QList<QTreeWidgetItem*>::const_iterator iter = selectedItem.begin(); iter != selectedItem.end(); ++iter)
        {
            QVariant typeData = (*iter)->data(0, FAMILY_USER_DATA_ROLE);
            nodeType = nodeType | typeData.toInt();
        }
        if (nodeType == TWNT_FAMILY)
        {
            /*/ TODO：相关命令后续实现*/
            if (m_bShowFamilyManagementMenuItem)
            {
                QAction* pRemoveFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"删除")));
                connect(pRemoveFamilyAction, SIGNAL(triggered(bool)), this, SLOT(RemoveFamily()));
            }
        }
    }
}

void Sample::ModelViewDlg::UpdateImportedObjectTreeItemContextMenu(const QList<QTreeWidgetItem*>& selectedItem)
{
    m_treeMenu->clear();

    if (selectedItem.size() == 1)
    {
        // 单选
        int nodeType = selectedItem[0]->data(0, IMPORT_USER_DATA_ROLE).toInt();

        /*/ TODO：相关命令后续实现
        if (nodeType == TWNT_CAD_SHEET)
        {
            QAction* pRemoveFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"删除")));
            connect(pRemoveFamilyAction, SIGNAL(triggered(bool)), this, SLOT(RemoveImportedObject()));
        }
        else if (nodeType == TWNT_SKP_MODEL)
        {
            QAction* pCreateFamilyInstance = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"创建实例")));
            connect(pCreateFamilyInstance, SIGNAL(triggered(bool)), this, SLOT(CreateFamilyInstance()));

            QAction* pRemoveFamilyAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"删除")));
            connect(pRemoveFamilyAction, SIGNAL(triggered(bool)), this, SLOT(RemoveFamily()));
        }
        */
    }
}

void Sample::ModelViewDlg::UpdateGroupObjectTreeItemContextMenu(const QList<QTreeWidgetItem*>& selectedItem)
{
    m_treeMenu->clear();

    if (selectedItem.size() == 1)
    {
        // 单选
        int nodeType = selectedItem[0]->data(0, GROUP_USER_DATA_ROLE).toInt();
        if (nodeType == TWNT_GROUP_MODEL)
        {
            QAction* pCreateFamilyInstance = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"创建组")));
            connect(pCreateFamilyInstance, SIGNAL(triggered(bool)), this, SLOT(CreateGroup()));

            QAction* pRemoveAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"删除")));
            connect(pRemoveAction, SIGNAL(triggered(bool)), this, SLOT(DeleteGroupType()));

            QAction* pRenameAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"重命名")));
            connect(pRenameAction, SIGNAL(triggered(bool)), this, SLOT(RenameGroupType()));

            QAction* pEditGroupTypeAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"编辑组类型")));
            connect(pEditGroupTypeAction, SIGNAL(triggered(bool)), this, SLOT(EditGroupType()));
        }
    }
    for (int i = 0; i < selectedItem.size(); ++i)
    {
        int nodeType = selectedItem[i]->data(0, GROUP_USER_DATA_ROLE).toInt();
        if (nodeType != TWNT_GROUP_MODEL)
        {
            return;
        }
    }
    QAction* pExportAction = m_treeMenu->addAction(QString::fromStdWString(GBMP_TR(L"导出组")));
    connect(pExportAction, SIGNAL(triggered(bool)), this, SLOT(ExportGroupType()));
}

void Sample::ModelViewDlg::CreateGroup()
{
    /*/ TODO：相关命令后续实现
    QFamilyTreeWidgetUtil::TrigerGroupAction(m_ui->modelViewTree->currentItem(), ID_CMD_CREATE_GROUP_BY_TYPE, ID_CMD_CREATE_GROUP_BY_TYPE);
    */
}

void Sample::ModelViewDlg::DeleteGroupType()
{
    /*/ TODO：相关命令后续实现
    QFamilyTreeWidgetUtil::TrigerGroupAction(m_ui->modelViewTree->currentItem(), ID_CMD_CREATE_GROUP_BY_TYPE, ID_CMD_DELETE_GROUP_TYPE);
    */
}

void Sample::ModelViewDlg::RenameGroupType()
{
    /*/ TODO：相关命令后续实现
    QFamilyTreeWidgetUtil::TrigerGroupAction(m_ui->modelViewTree->currentItem(), ID_CMD_CREATE_GROUP_BY_TYPE, ID_CMD_RENAME_GROUP_TYPE);
    */
}

void Sample::ModelViewDlg::ExportGroupType()
{
    /*/ TODO：相关命令后续实现
    QFamilyTreeWidgetUtil::TrigerGroupListAction(m_ui->modelViewTree->selectedItems(), ID_CMD_CREATE_GROUP_BY_TYPE, ID_CMD_EXPORT_GROUP_TYPE);
    */
}

void Sample::ModelViewDlg::EditGroupType()
{
    /*/ TODO：相关命令后续实现
    QFamilyTreeWidgetUtil::TrigerGroupAction(m_ui->modelViewTree->currentItem(), ID_CMD_EDIT_GROUP_TYPE, ID_CMD_EDIT_GROUP_TYPE);
    */
}

void Sample::ModelViewDlg::CreateOpen3DView()
{
    ICommandManager* pCommandManager = ICommandManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pCommandManager, L"ICommandManager::Get()返回空指针",L"GDMP",L"2023-10-20");
    pCommandManager->SendCommand(Sample::COMMAND_VIEW_3D);
}

void Sample::ModelViewDlg::CreateOpenPlanView()
{
    ICommandManager* pCommandManager = ICommandManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pCommandManager, L"ICommandManager::Get()返回空指针",L"GDMP",L"2023-10-20");
    pCommandManager->SendCommand(Sample::COMMAND_VIEW_2D);
}

void Sample::ModelViewDlg::CreateOpenSectionView()
{
    ICommandManager* pCommandManager = ICommandManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pCommandManager, L"ICommandManager::Get()返回空指针",L"GDMP",L"2023-10-20");
    pCommandManager->SendCommand(Sample::COMMAND_VIEW_VERTICAL);
}

void Sample::ModelViewDlg::CreateLayout()
{
    gcmp::IUiView* pUiViewDrawing;
    UiPlatformUtils::CreateUiViewDrawing(UiDocumentViewUtils::GetCurrentUiDocument(), L"", pUiViewDrawing);
}

void Sample::ModelViewDlg::CreateFamilyInstance()
{
    QFamilyTreeWidgetUtil::CreateFamilyInstance(m_ui->modelViewTree->currentItem(), ID_CMD_FAMILY_CREATE_INSTANCE);
}

void Sample::ModelViewDlg::RenameFamily()
{
    QFamilyTreeWidgetUtil::RenameFamily(m_ui->modelViewTree->currentItem(), ID_CMD_FAMILY_RENAME);
}

void Sample::ModelViewDlg::EditFamily()
{
    QFamilyTreeWidgetUtil::EditFamily(m_ui->modelViewTree->currentItem(), ID_CMD_FAMILY_EDIT);
}

void Sample::ModelViewDlg::SaveAsFamily()
{
    QFamilyTreeWidgetUtil::SaveFamilyAs(m_ui->modelViewTree->currentItem(), ID_CMD_FAMILY_SAVE_AS);
}

void Sample::ModelViewDlg::LoadFamily()
{
    QFamilyTreeWidgetUtil::LoadFamily(m_ui->modelViewTree->currentItem(), ID_CMD_FAMILY_LOAD);
}

void Sample::ModelViewDlg::LoadSubFamily()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_ui->modelViewTree, L"modelViewTree为空",L"GDMP",L"2023-10-20");

    QFamilyTreeWidgetUtil::LoadFamily(m_ui->modelViewTree->currentItem(), ID_CMD_FAMILY_LOAD_SUB);
}

void Sample::ModelViewDlg::RemoveFamily()
{
    QFamilyTreeWidgetUtil::RemoveSelectedFamlies(m_ui->modelViewTree->selectedItems(), ID_CMD_FAMILY_REMOVE);
}

void Sample::ModelViewDlg::OnModelViewTreeItemDoubleClicked(QTreeWidgetItem *item, int column)
{
    if (item == nullptr)
        return;
    Int64 viewId = 0;

    IUiDocument* pUIDoc = GetUiDocumentViewManager()->GetUiDocumentByRuntimeId(m_uiDocID);
    if (pUIDoc == nullptr)
        return;

    QTreeWidgetItem* pItem = GetSelectedViewPort();
    if (pItem)
    {
        std::wstring name = pItem->data(0, PAPER_USER_DATA_ROLE).toString().toStdWString();
        // TODO：后续做双击视口打开视图的处理
    }

    IDocument *pDbDoc = pUIDoc->GetDbDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDbDoc != nullptr, L"pDbDoc为空",L"GDMP",L"2023-10-20");

    if (item->data(0, FAMILY_USER_DATA_ROLE).isValid())
    {
        QFamilyTreeWidgetUtil::EditFamilyTypeParameter(item);
        m_opUiLayoutManager->SetCurrentLayout(ElementId::InvalidID);
        m_opUiLayoutManager->SetCurrentViewport(ElementId::InvalidID);
    }
    else if (item->data(0, PAPER_USER_DATA_ROLE).isValid())
    {
        if (item->data(0, PAPER_USER_DATA_ROLE).toString().toStdWString() == L"Drawing Layout")
        {
            std::wstring paperItemName = item->text(0).toStdWString();
            std::wstring errorMessage = L"";
            IDrawingLayoutManager* pLayoutManager = IDrawingLayoutManager::Get(pDbDoc, &errorMessage);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pLayoutManager, L"pLayoutManager为空",L"GDMP",L"2023-10-20");
            IDrawingLayout* pLayout = pLayoutManager->GetLayout(paperItemName);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pLayout, L"pLayout为空",L"GDMP",L"2023-10-20");

            m_opUiLayoutManager->SetCurrentLayout(pLayout->GetOwnerElement()->GetElementId());
            m_opUiLayoutManager->SetCurrentViewport(ElementId::InvalidID);
            IModelView* pPaperModelView = pLayout->GetModelView();
            IUiView* pCurrentUiView = GetUiDocumentViewManager()->GetCurrentUiView();
            DBG_WARN_AND_RETURN_VOID_UNLESS(pCurrentUiView, L"pCurrentUiView为空",L"GDMP",L"2023-10-20");
            IModelView* pCurrentModel = pCurrentUiView->GetModelView();
            if (pCurrentModel && pCurrentModel->GetName() == paperItemName)
            {
                PropertyPalette* pPropertyPalette = PropertyPalette::GetPropertyPalette();
                pPropertyPalette->CheckDocSwitched();
                pPropertyPalette->Refresh(true);
                IMainWindow::GetMainWindow()->CreateOrOpenUiView(pUIDoc->GetId(), pPaperModelView->GetElementId(), false, L"");
                return;
            }
            if (pPaperModelView)
            {
                viewId = pPaperModelView->GetBasicInformation()->GetElementId().AsInt64();
            }
            else
                return;
        }
        else
        {
            //视口切换
            std::wstring errorMessage = L"";
            IDrawingLayoutManager* pLayoutManager = IDrawingLayoutManager::Get(pDbDoc, &errorMessage);
            DBG_WARN_AND_RETURN_VOID_UNLESS(pLayoutManager, L"pLayoutManager为空",L"GDMP",L"2023-10-20");
            IDrawingLayout* pViewPortCorrespondedToLayout = pLayoutManager->GetLayout(item->parent()->text(0).toStdWString());
            DBG_WARN_AND_RETURN_VOID_UNLESS(pViewPortCorrespondedToLayout, L"pViewPortCorrespondedToLayout为空,",L"GDMP",L"2023-10-20");
            IDrawingViewport* pViewPort = pViewPortCorrespondedToLayout->GetViewport(item->text(0).toStdWString());
            DBG_WARN_AND_RETURN_VOID_UNLESS(pViewPort, L"pViewPort为空,",L"GDMP",L"2023-10-20");
            m_opUiLayoutManager->SetCurrentViewport(pViewPort->GetOwnerElement()->GetElementId());
            m_opUiLayoutManager->SetCurrentLayout(ElementId::InvalidID);
            HighLightSelectedViewport(item);
            item->setBackgroundColor(0, QColor(170, 179, 173));
            item->setSelected(true);
            PropertyPalette* pPropertyPalette = PropertyPalette::GetPropertyPalette();
            pPropertyPalette->CheckDocSwitched();
            pPropertyPalette->Refresh(true);
            return;
        }
    }
    else
    {
        // 得到选中的ModelView。
        QVariant data = item->data(0, MODEL_VIEW_USER_DATA_ROLE);
        viewId = data.toLongLong();

        m_opUiLayoutManager->SetCurrentLayout(ElementId::InvalidID);
        m_opUiLayoutManager->SetCurrentViewport(ElementId::InvalidID);
    }

    ElementId modelViewId(viewId);
    if (!modelViewId.IsValid())
        return;

    IModelView* pModelView = quick_cast<IModelView>(pDbDoc->GetElement(modelViewId));
    if (pModelView == nullptr)
        return;

    /*/ TODO：后续需要增加图纸视口切换 */
    IApplication* pApp = IApplication::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pApp, L"invalid pApp",L"GDMP",L"2023-10-20");
    IMainWindow* pMainWin = IMainWindow::GetMainWindow();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pMainWin, L"invalid pMainWin",L"GDMP",L"2023-10-20");
    if (pModelView->GetViewType() == BuiltInViewType::Drawing)
    {
        IUiView* pView = pMainWin->CreateOrOpenUiView(pUIDoc->GetId(), pModelView->GetElementId(), false, L"");
        DBG_WARN_AND_RETURN_VOID_UNLESS(pView, L"invalid pView",L"GDMP",L"2023-10-20");
        HighlightSelectedModelView(pView);
        return;
    }

    IUiView* pView = pMainWin->CreateOrOpenUiView(m_uiDocID, ElementId(viewId), false, L"");
    if (pView == nullptr)
        return;
    ICanvas *pCanvas = pView->GetCanvas();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pCanvas, L"pCanvas is null",L"GDMP",L"2023-10-20");
    pCanvas->RefreshByVisibilityConditionChanged();
    if (IActionManager::CurrentAction() == nullptr)
    {
        //进入到默认工具
        ICommandManager *pCmdMgr = ICommandManager::Get();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pCmdMgr != nullptr, L"pCmdMgr为空",L"GDMP",L"2023-10-20");
        pCmdMgr->SendCommand(GetUiDocumentViewManager()->GetCurrentUiView()->GetDefaultActionCommand());
    }
    HighlightSelectedModelView(pView);
}

QTreeWidgetItem* Sample::ModelViewDlg::InitViewType(const std::wstring& viewType)
{
    std::wstring typeName;
    typeName = ModelViewUtils::GetModelViewTypeName(viewType);

    for (int i = 0; i < m_ui->modelViewTree->topLevelItemCount(); ++i)
    {
        QTreeWidgetItem* pItemViewType = m_ui->modelViewTree->topLevelItem(i);
        DBG_WARN_AND_CONTINUE_UNLESS(pItemViewType, L"pItemViewType为空",L"GDMP",L"2023-10-20");
        if (pItemViewType)
        {
            std::wstring itemType = pItemViewType->data(0, Qt::UserRole).toString().toStdWString();
            if (itemType == typeName)
                return pItemViewType;
        }
    }

    OwnerPtr<QTreeWidgetItem> itemViewType = NEW_AS_OWNER_PTR(QTreeWidgetItem, QStringList(QString::fromStdWString(typeName)));
    itemViewType->setData(0, Qt::UserRole, QString::fromStdWString(typeName));
    itemViewType->setData(1, Qt::UserRole, QString::fromStdWString(viewType));

    if (viewType == PlanViewType)
    {
        itemViewType->setIcon(0, QIcon(QString::fromStdWString(L":/images/View/平面视图_16px.png")));
    }
    else if (viewType == View3DViewType || viewType == View3DViewTypePerspective)
    {
        itemViewType->setIcon(0, QIcon(QString::fromStdWString(L":/images/View/三维视图_16px.png")));
    }
    else if (viewType == SectionViewType)  // 剖面视图
    {
        itemViewType->setIcon(0, QIcon(QString::fromStdWString(L":/images/View/剖切视图_16px.png")));
    }
    else
    {
        itemViewType->setIcon(0, QIcon(QString::fromStdWString(L":/images/View/图纸_16px.png")));
    }

    QTreeWidgetItem* topViewTypeItem = itemViewType.get();

    if (ShowTwoDimensionalDrawing)
    {
        /*/ TODO：待二维出图功能完成 */
        QTreeWidgetItem *pPaperRoot = GetRootPaperItem();
        if (pPaperRoot != nullptr)
        {
            int nIndex = m_ui->modelViewTree->indexOfTopLevelItem(pPaperRoot);
            if (nIndex >= 0)
            {
                m_ui->modelViewTree->insertTopLevelItem(nIndex, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(itemViewType));
            }
        }

        if (ShowFamilyInSeperatedTree)
        {
            m_ui->modelViewTree->addTopLevelItem(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(itemViewType));
        }
        else
        {
            QTreeWidgetItem *pFamilyRoot = GetRootFamilyItem();
            if (pFamilyRoot != nullptr)
            {
                QTreeWidget* pModelViewTree = m_ui->modelViewTree;
                if (nullptr != pModelViewTree)
                {
                    int nIndex = pModelViewTree->indexOfTopLevelItem(pFamilyRoot);
                    if (nIndex >= 0)
                    {
                        QTreeWidgetItem* pTopLevelItem = pModelViewTree->takeTopLevelItem(nIndex);
                        if (nullptr != pTopLevelItem)
                        {
                            // 智能指针在这用于释放pTopLevelItem所占用的内存
                            OwnerPtr<QTreeWidgetItem> opTopLevelItem(pTopLevelItem);
                            pModelViewTree->removeItemWidget(pTopLevelItem, 0);
                        }
                    }

                    InitFamilyTree();
                    if (nIndex >= 0)
                    {
                        pModelViewTree->insertTopLevelItem(nIndex, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(itemViewType));
                    }
                }
            }
        }
    }
    else
    {
        QTreeWidgetItem *pPaperRoot = GetRootPaperItem();
        if (pPaperRoot != nullptr)
        {
            QTreeWidget* pModelViewTree = m_ui->modelViewTree;
            if (nullptr != pModelViewTree)
            {
                int nIndex = pModelViewTree->indexOfTopLevelItem(pPaperRoot);
                if (nIndex >= 0)
                {
                    QTreeWidgetItem* pPaper = pModelViewTree->takeTopLevelItem(nIndex);
                    if (nullptr != pPaper)
                    {
                        OwnerPtr<QTreeWidgetItem> opPaper(pPaper);
                        pModelViewTree->removeItemWidget(pPaper, 0);
                    }
                }
            }
        }

        if (ShowFamilyInSeperatedTree)
        {
            m_ui->modelViewTree->addTopLevelItem(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(itemViewType));
        }
        else
        {
            QTreeWidgetItem *pFamilyRoot = GetRootFamilyItem();
            if (pFamilyRoot != nullptr)
            {
                int nIndex = m_ui->modelViewTree->indexOfTopLevelItem(pFamilyRoot);
                if (nIndex >= 0)
                {
                    m_ui->modelViewTree->insertTopLevelItem(nIndex, TRANSFER_OWNERSHIP_TO_THIRD_PARTY(itemViewType));
                }
            }
        }
    }
    //待二维出图功能完成，去掉DebugMode后去掉该部分，放开上面注释部分即可

    return topViewTypeItem;
}

void Sample::ModelViewDlg::Init(gcmp::IUiDocument* pUIDoc)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUIDoc != nullptr, L"pUIDoc为空",L"GDMP",L"2023-10-20");

    //缓存uiDoc
    m_uiDocID = pUIDoc->GetId();

    //用缓存的uiDoc刷新
    Refresh();
}

void Sample::ModelViewDlg::UpdateModelViewsTree(IUiDocument* pUIDoc)
{
    ClearModelViewsItem();

    DBG_WARN_AND_RETURN_VOID_UNLESS(pUIDoc != nullptr, L"pUIDoc为空",L"GDMP",L"2023-10-20");

    IDocument *pDbDoc = pUIDoc->GetDbDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDbDoc != nullptr, L"pDbDoc为空",L"GDMP",L"2023-10-20");

    std::vector<IModelView *> modelViews = IModelView::GetAllModelViews(pDbDoc);
    std::map<std::wstring, int> standNamePriorityMap = { { L"前",0 },{ L"后",1 },{L"左",2},{L"右",3} };//族编辑器 立面排序
    auto modelViewCompare = [](const IModelView* pView1, const IModelView* pView2)
    {
        if (pView1 == nullptr || pView2 == nullptr)
            return false;
        if (pView1->GetViewType() < pView2->GetViewType())
            return true;
        else
            return false;
    };
    auto modelViewCompareNameCompare = [&standNamePriorityMap](const IModelView* pView1, const IModelView* pView2)
    {
        if (pView1 == nullptr || pView2 == nullptr)
            return false;
        std::wstring viewType1 = pView1->GetBasicInformation()->GetName();
        std::wstring viewType2 = pView2->GetBasicInformation()->GetName();
        auto it1 = standNamePriorityMap.find(viewType1);
        auto it2 = standNamePriorityMap.find(viewType2);
        if (it1 != standNamePriorityMap.end() && it2 != standNamePriorityMap.end())
        {
            if (it1->second < it2->second)
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        else
        {
            if (pView1->GetViewType() < pView2->GetViewType())
                return true;
            else
                return false;
        }
    };
    std::stable_sort(modelViews.begin(), modelViews.end(), modelViewCompare);//目前仅实现按模型类别排序，其他复杂的规则todo
    std::stable_sort(modelViews.begin(), modelViews.end(), modelViewCompareNameCompare);
    InitViewType(PlanViewType);
    InitViewType(SectionViewType);
    InitViewType(View3DViewType);

    for (int i = 0; i < (int)modelViews.size(); ++i)
    {
        IModelView* pModelView = modelViews[i];
        DBG_WARN_AND_CONTINUE_UNLESS(pModelView != nullptr, L"pModelView为空",L"GDMP",L"2023-10-20");

        std::wstring strName = pModelView->GetBasicInformation()->GetName();
        if (pModelView->GetViewType() == BuiltInViewType::Drawing)
        {
            continue;
        }

        QTreeWidgetItem * parentItem = InitViewType(pModelView->GetUserDataId());

        if (parentItem)
        {
            OwnerPtr<QTreeWidgetItem> childItemView = NEW_AS_OWNER_PTR(QTreeWidgetItem, parentItem, QStringList(QString::fromStdWString(strName))); //子节点1
            childItemView->setData(0, MODEL_VIEW_USER_DATA_ROLE, pModelView->GetBasicInformation()->GetElementId().AsInt64());
            parentItem->addChild(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(childItemView)); //添加子节点
        }
    }
    ExpandAllModelViewItems();
}

void Sample::ModelViewDlg::ExpandAllModelViewItems()
{
    for (int i = 0; i < m_ui->modelViewTree->topLevelItemCount(); ++i)
    {
        QTreeWidgetItem *pTopLevelItem = m_ui->modelViewTree->topLevelItem(i);
        if (pTopLevelItem->data(0, Qt::UserRole).isValid())
        {
            pTopLevelItem->setExpanded(true);
        }
    }
}

void Sample::ModelViewDlg::ClearModelViewsItem()
{
    for (int i = 0; i < m_ui->modelViewTree->topLevelItemCount();)
    {
        QTreeWidgetItem *pTopLevelItem = m_ui->modelViewTree->topLevelItem(i);
        if (pTopLevelItem->data(0, Qt::UserRole).isValid())
        {
            OwnerPtr<QTreeWidgetItem> opTopLevelItem(m_ui->modelViewTree->takeTopLevelItem(i));
        }
        else
        {
            ++i;
        }
    }
}

void Sample::ModelViewDlg::Refresh()
{
    IUiDocumentViewManager* pUiDocViewMgr = GetUiDocumentViewManager();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDocViewMgr != nullptr, L"pUiDocViewMgr为空",L"GDMP",L"2023-10-20");

    IUiDocument* pUiDoc = pUiDocViewMgr->GetUiDocumentByRuntimeId(m_uiDocID);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUiDoc != nullptr, L"pUiDoc为空",L"GDMP",L"2023-10-20");

    //1) 更新视图管理器的视图
    UpdateModelViewsTree(pUiDoc);

    if (ShowTwoDimensionalDrawing)
    {
        //更新图纸管理器的视图
        UpdatePaperTreeView(pUiDoc->GetDbDocument());
    }

    //2) 更新构件族管理器的视图
    UpdateFamiliesTreeView(pUiDoc->GetDbDocument());

    UpdateImportedObjectsTreeView(pUiDoc->GetDbDocument());

    UpdateGroupObjectsTreeView(pUiDoc->GetDbDocument());

    //重置更新标记
    m_isNeedUpdate = false;

    // 设置当前视图为选中状态
    HighlightSelectedModelView(pUiDocViewMgr->GetCurrentUiView());
}

void Sample::ModelViewDlg::HighlightSelectedModelView(const IUiView* pUIView)
{
    if (!pUIView)
        return;

    // 视图名称。
    gcmp::IModelView* pModelView = pUIView->GetModelView();
    std::wstring viewName = pModelView != nullptr ? pModelView->GetBasicInformation()->GetName() : L"";

    QList<QTreeWidgetItem*> viewTypeItems = m_ui->modelViewTree->findItems(QString(QStringLiteral("")), Qt::MatchContains);
    for (auto it = viewTypeItems.begin(); it != viewTypeItems.end(); ++it)
    {
        QTreeWidgetItem* viewTypeItem = dynamic_cast<QTreeWidgetItem*>(*it);
        for (int i = 0; i < viewTypeItem->childCount(); ++i)
        {
            QTreeWidgetItem* viewItem = viewTypeItem->child(i);
            std::wstring viewText = viewItem->text(0).toStdWString();

            if (viewItem->data(0, PAPER_USER_DATA_ROLE).isValid())
            {
                if (viewText == viewName)
                {
                    viewItem->setBackgroundColor(0, QColor(170, 179, 173));
                    viewItem->setSelected(true);
                }
                else
                {
                    viewItem->setSelected(false);
                    viewItem->setBackgroundColor(0, QColor(255, 255, 255));
                }
            }
            else
            {
                Int64 viewId = viewItem->data(0, MODEL_VIEW_USER_DATA_ROLE).toLongLong();
                if (viewText == viewName && pModelView->GetBasicInformation()->GetElementId().AsInt64() == viewId)
                {
                    viewItem->setBackgroundColor(0, QColor(170, 179, 173));
                    viewItem->setSelected(true);
                }
                else
                {
                    viewItem->setSelected(false);
                    viewItem->setBackgroundColor(0, QColor(255, 255, 255));
                }
            }

        }
    }
}

void Sample::ModelViewDlg::HighLightSelectedViewport(QTreeWidgetItem* pViewportItem)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pViewportItem, L"pViewportItem为空",L"GDMP",L"2023-10-20");
    QTreeWidgetItem* pPaperRoot = GetRootPaperItem();
    for (int i = 0; i < pPaperRoot->childCount(); ++i)
    {
        QTreeWidgetItem* pPaperItem = pPaperRoot->child(i);
        for (int j = 0; j < pPaperItem->childCount(); ++j)
        {
            QTreeWidgetItem* pViewPort = pPaperItem->child(j);
            if (pViewPort == pViewportItem)
            {
                pViewPort->setBackgroundColor(0, QColor(170, 179, 173));
                pViewPort->setSelected(true);
            }
            else
            {
                pViewPort->setSelected(false);
                pViewPort->setBackgroundColor(0, QColor(255, 255, 255));
            }
        }
    }
}

QSize Sample::ModelViewDlg::sizeHint() const
{
    return QSize(200, 900);
}

void Sample::ModelViewDlg::RemoveSelectedModelView()
{
    /*/ TODO
    QTreeWidgetItem* pViewItem = m_ui->modelViewTree->currentItem();
    if (pViewItem != nullptr)
    {
        QVariant data = pViewItem->data(0, MODEL_VIEW_USER_DATA_ROLE);
        Int64 viewId = data.toLongLong();

        IUiDocument* pUIDoc = GetUiDocumentViewManager()->GetCurrentUiDocument();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pUIDoc != nullptr, L"pUIDoc不能为空",L"GDMP",L"2023-10-20");
        IDocument *pDoc = pUIDoc->GetDbDocument();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc != nullptr, L"pDoc不能为空",L"GDMP",L"2023-10-20");

        ElementId modelviewId(viewId);
        IModelView* pModelView = quick_cast<IModelView>(pDoc->GetElement(modelviewId));
        DBG_WARN_AND_RETURN_VOID_UNLESS(pModelView != nullptr, L"找不到要删除的视图",L"GDMP",L"2023-10-20");
#pragma warning(push)
#pragma warning(disable: 4996)
        std::wstring modelViewType = pModelView->GetUserDataId();
#pragma warning(pop)
        std::wstring modelViewName = pModelView->GetBasicInformation()->GetName();

        CommandParameters cmdParams;
        cmdParams.emplace(L"ModelViewType", modelViewType);
        cmdParams.emplace(L"ModelViewName", modelViewName);

        OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
        DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
        opJournalCmdData->SetCommandName(ID_CMD_REMOVE_SELECTED_MODEL_VIEW);
        opJournalCmdData->SetParameterArray(cmdParams);
        JournalUtils::RecordCommand(TransferOwnership(opJournalCmdData));

        ICommandManager::Get()->SendCommand(ID_CMD_REMOVE_SELECTED_MODEL_VIEW, cmdParams);
    }
    */
}

void Sample::ModelViewDlg::AttachEventHandler(gcmp::IUiDocument* pUIDoc)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUIDoc, L"pUIDoc不能为空",L"GDMP",L"2023-10-20");

    IDocument* pDoc = pUIDoc->GetDbDocument();
    if (pDoc)
    {
        pDoc->AddElementsChangeEventHandler(ElementsChangeEventType::ElementsAdditionEvent, m_pElementChangeEventHandler.get());
        pDoc->AddElementsChangeEventHandler(ElementsChangeEventType::ElementsPreDeletionEvent, m_pElementChangeEventHandler.get());
        pDoc->AddElementsChangeEventHandler(ElementsChangeEventType::ElementsPostUpdationEvent, m_pElementChangeEventHandler.get());

        IUndoRedoEvent* pUndoRedoEvent = pDoc->GetUndoRedoEvent();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pUndoRedoEvent, L"pUndoRedoEvent不能为空",L"GDMP",L"2023-10-20");
        pUndoRedoEvent->Add(m_pUndoRedoEventHandler.get());

        ITransactionEvent* pTransactionEvent = pDoc->GetTransactionEvent();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pTransactionEvent, L"pTransactionEvent不能为空",L"GDMP",L"2023-10-20");
        pTransactionEvent->Add(m_pTransactionEventHandler.get());
    }
}

void Sample::ModelViewDlg::RemoveSelectedPaperOrViewPort()
{
    /*/ TODO
    QTreeWidgetItem* pCurrentItem = m_ui->modelViewTree->currentItem();
    std::wstring itemType = L"";
    std::wstring itemName = L"";
    std::wstring currentLayoutName = L"";
    std::wstring ViewportCorrespondedToLayout = L"";

    IUiDocument* pUIDoc = GetUiDocumentViewManager()->GetCurrentUiDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUIDoc, L"pUIDoc为空",L"GDMP",L"2023-10-20");
    IDocument *pDoc = pUIDoc->GetDbDocument();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pDoc, L"pDoc为空",L"GDMP",L"2023-10-20");

    if (pCurrentItem && pCurrentItem->data(0, PAPER_USER_DATA_ROLE).isValid())
    {
        itemType = pCurrentItem->data(0, PAPER_USER_DATA_ROLE).toString().toStdWString();
        itemName = pCurrentItem->text(0).toStdWString();

        IDrawingLayout* pCurrentLayout = m_opUiLayoutManager->GetCurrentLayout(pDoc);
        if (pCurrentLayout)
            currentLayoutName = pCurrentLayout->GetName();

        if (itemType == L"Drawing Viewport")
        {
            ViewportCorrespondedToLayout = pCurrentItem->parent()->text(0).toStdWString();
        }
    }
    else
        return;

    CommandParameters cmdParams;
    cmdParams.emplace(L"itemType", itemType);
    cmdParams.emplace(L"itemName", itemName);
    cmdParams.emplace(L"currentLayoutName", currentLayoutName);
    cmdParams.emplace(L"ViewportCorrespondedToLayout",ViewportCorrespondedToLayout);

    OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
    DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"CREATE_JOURNAL_DATA(IJournalCommandData, JOURNAL_COMMAND_DATA)返回空指针",L"GDMP",L"2023-10-20");
    opJournalCmdData->SetCommandName(ID_CMD_REMOVE_SELECTED_PAPER_OR_VIEWPORT);
    opJournalCmdData->SetParameterArray(cmdParams);
    JournalUtils::RecordCommand(TransferOwnership(opJournalCmdData));

    ICommandManager::Get()->SendCommand(ID_CMD_REMOVE_SELECTED_PAPER_OR_VIEWPORT, cmdParams);
    */
}

void Sample::ModelViewDlg::DetachEventHandler(gcmp::IUiDocument* pUIDoc)
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(pUIDoc != nullptr, L"pUIDoc不能为空",L"GDMP",L"2023-10-20");

    IDocument* pDoc = pUIDoc->GetDbDocument();
    if (pDoc)
    {
        pDoc->DeleteElementsChangeEventHandler(ElementsChangeEventType::ElementsAdditionEvent, m_pElementChangeEventHandler.get());
        pDoc->DeleteElementsChangeEventHandler(ElementsChangeEventType::ElementsPreDeletionEvent, m_pElementChangeEventHandler.get());
        pDoc->DeleteElementsChangeEventHandler(ElementsChangeEventType::ElementsPostUpdationEvent, m_pElementChangeEventHandler.get());

        IUndoRedoEvent* pUndoRedoEvent = pDoc->GetUndoRedoEvent();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pUndoRedoEvent, L"pUndoRedoEvent不能为空",L"GDMP",L"2023-10-20");
        pUndoRedoEvent->Delete(m_pUndoRedoEventHandler.get());

        ITransactionEvent* pTransactionEvent = pDoc->GetTransactionEvent();
        DBG_WARN_AND_RETURN_VOID_UNLESS(pTransactionEvent, L"pTransactionEvent不能为空",L"GDMP",L"2023-10-20");
        pTransactionEvent->Delete(m_pTransactionEventHandler.get());
    }
}

void Sample::ModelViewDlg::InitPaperTree()
{
    std::wstring viewType = DrawingLayoutViewType;
    std::wstring typeName = ModelViewUtils::GetModelViewTypeName(viewType);
    OwnerPtr<QTreeWidgetItem> rootItem = NEW_AS_OWNER_PTR(QTreeWidgetItem, QStringList(QString::fromStdWString(GBMP_TR(L"图纸"))));
    rootItem->setIcon(0, QIcon(QString::fromStdWString(L":/images/View/图纸_16px.png")));
    rootItem->setData(0, Qt::UserRole, QString::fromStdWString(typeName));
    rootItem->setData(1, Qt::UserRole, QString::fromStdWString(viewType));
    m_ui->modelViewTree->addTopLevelItem(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(rootItem));
}

void Sample::ModelViewDlg::UpdatePaperTreeView(IDocument* pDoc)
{
    QTreeWidgetItem *pPaperRoot = GetRootPaperItem();
    if (pPaperRoot == nullptr)
    {
        InitPaperTree();
        pPaperRoot = GetRootPaperItem();
    }
    std::wstring errorMessage = L"";
    const IDrawingLayoutManager* pLayoutsManager = IDrawingLayoutManager::Get(pDoc, &errorMessage);
    DBG_WARN_AND_RETURN_VOID_UNLESS(pLayoutsManager, L"pLayoutsManager为空",L"GDMP",L"2023-10-20");
    std::vector<IDrawingLayout*> layouts = pLayoutsManager->GetAllLayouts();
    if ((layouts.size() == 0) || (layouts.size() && QTreeWidgetPaper::FindChildWidgetItem(layouts[layouts.size() - 1]->GetName()) == nullptr))
    {
        QTreeWidgetPaper::UpdatePaperItems(pPaperRoot, pDoc);
    }
}

QTreeWidgetItem* Sample::ModelViewDlg::GetRootPaperItem()
{
    QTreeWidgetItem *pRootPaperItem = nullptr;
    for (int i = 0; i < m_ui->modelViewTree->topLevelItemCount(); ++i)
    {
        QTreeWidgetItem* pTopLevelItem = m_ui->modelViewTree->topLevelItem(i);
        QString curTitle = pTopLevelItem->text(0);
        if (curTitle == QString::fromStdWString(GBMP_TR(L"图纸")))
        {
            return pTopLevelItem;
        }
    }
    return nullptr;
}

QTreeWidgetItem* Sample::ModelViewDlg::GetSelectedPaper()
{
    QTreeWidgetItem* pSelectedItem = m_ui->modelViewTree->currentItem();
    if (pSelectedItem && pSelectedItem->data(0, PAPER_USER_DATA_ROLE).toString().toStdWString() == L"Drawing Layout")
    {
        return pSelectedItem;
    }
    return nullptr;
}

QTreeWidgetItem* Sample::ModelViewDlg::GetSelectedViewPort()
{
    QTreeWidgetItem* pSelectedItem = m_ui->modelViewTree->currentItem();
    if (pSelectedItem && pSelectedItem->data(0, PAPER_USER_DATA_ROLE).toString().toStdWString() == L"Drawing Viewport")
    {
        return pSelectedItem;
    }
    return nullptr;
}

UiLayoutManager* Sample::ModelViewDlg::GetUiLayoutManager() const
{
    return const_cast<UiLayoutManager*>(m_opUiLayoutManager.get());
}

void Sample::ModelViewDlg::InitFamilyTree()
{
    if (ShowFamilyInSeperatedTree)
    {
        m_pFamilyTree = NEW_AS_QT_CHILD(QFamilyTreeWidget, this);
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pFamilyTree != nullptr, L"m_pFamilyTree为空",L"GDMP",L"2023-10-20");
        m_pFamilyTree->setObjectName(QStringLiteral("familyTree"));
        m_ui->verticalLayout->addWidget(m_pFamilyTree);
        m_pFamilyTree->header()->setVisible(false);

        OwnerPtr<QTreeWidgetItem> rootItem = NEW_AS_OWNER_PTR(QTreeWidgetItem, m_pFamilyTree, QStringList(QFamilyTreeWidgetUtil::s_familyText));
        m_pFamilyTree->addTopLevelItem(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(rootItem));
    }
    else
    {
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_ui && m_ui->modelViewTree, L"modelViewTree不能为空",L"GDMP",L"2023-10-20");
        OwnerPtr<QTreeWidgetItem> rootItem = NEW_AS_OWNER_PTR(QTreeWidgetItem, m_ui->modelViewTree, QStringList(QFamilyTreeWidgetUtil::s_familyText));
        m_ui->modelViewTree->addTopLevelItem(TRANSFER_OWNERSHIP_TO_THIRD_PARTY(rootItem));
        if (m_pFamilyTree != nullptr)
        {
            m_ui->verticalLayout->removeWidget(m_pFamilyTree);
            m_pFamilyTree = nullptr;
        }
    }
}

void Sample::ModelViewDlg::InitImportedObjectTree()
{
    // 事务中会处理，这里不用初始化
}

void Sample::ModelViewDlg::InitGroupObjectTree()
{
    /*/ TODO
    if (DEBUG_MODE(ShowGroupObjectsInSeparatedTree))
    {
        m_pGroupObjectTree = NEW_AS_QT_CHILD(QGroupObjectTreeWidget, this);
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pGroupObjectTree && m_ui && m_ui->verticalLayout, L"verticalLayout不能为空",L"GDMP",L"2023-10-20");
        m_pGroupObjectTree->setObjectName(QStringLiteral("groupTree"));
        m_ui->verticalLayout->addWidget(m_pGroupObjectTree);

        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pGroupObjectTree->header(), L"m_pGroupObjectTree->header()不能为空",L"GDMP",L"2023-10-20");
        m_pGroupObjectTree->header()->setVisible(false);
        m_pGroupObjectTree->setVisible(false);
    }
    else
    {
        // 导入对象树不单独一个窗口
    }
    */
}

void Sample::ModelViewDlg::UpdateFamiliesTreeView(gcmp::IDocument* pDoc)
{
    if (ShowFamilyInSeperatedTree)
    {
        if (m_pFamilyTree == nullptr)
        {
            InitFamilyTree();
        }
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pFamilyTree != nullptr, L"m_pFamilyTree为空",L"GDMP",L"2023-10-20");
        m_pFamilyTree->UpdateView(pDoc);
    }
    else
    {
        QTreeWidgetItem *pFamilyRoot = GetRootFamilyItem();
        if (pFamilyRoot == nullptr)
        {
            InitFamilyTree();
            pFamilyRoot = GetRootFamilyItem();
        }
        QFamilyTreeWidgetUtil::UpdateFamilyItems(pFamilyRoot, pDoc, m_familyIcons);
    }
}

void Sample::ModelViewDlg::UpdateImportedObjectsTreeView(gcmp::IDocument* pDoc)
{
    QFamilyTreeWidgetUtil::UpdateImportedObjectItems(m_ui->modelViewTree, pDoc, m_familyIcons);
}

void Sample::ModelViewDlg::UpdateGroupObjectsTreeView(gcmp::IDocument* pDoc)
{
    /*/ TODO
    if (DEBUG_MODE(ShowGroupObjectsInSeparatedTree))
    {
        if (m_pGroupObjectTree == nullptr)
        {
            InitGroupObjectTree();
        }
        DBG_WARN_AND_RETURN_VOID_UNLESS(m_pGroupObjectTree != nullptr, L"m_pGroupObjectTree为空",L"GDMP",L"2023-10-20");
        m_pGroupObjectTree->UpdateView(pDoc);
    }
    else
    {
        QFamilyTreeWidgetUtil::UpdateGroupObjectItems(m_ui->modelViewTree, pDoc, m_familyIcons);
    }
    */
}

QTreeWidgetItem* Sample::ModelViewDlg::GetRootFamilyItem()
{
    QTreeWidgetItem *pRootFamilyItem = nullptr;
    if (ShowFamilyInSeperatedTree)
    {
        if (m_pFamilyTree != nullptr)
            return m_pFamilyTree->topLevelItem(0);
    }
    else
    {
        for (int i = 0; i < m_ui->modelViewTree->topLevelItemCount(); ++i)
        {
            QTreeWidgetItem *pTopLevelItem = m_ui->modelViewTree->topLevelItem(i);
            QString curTitle = pTopLevelItem->text(0);
            if (curTitle == QFamilyTreeWidgetUtil::s_familyText)
            {
                return pTopLevelItem;
            }
        }
    }
    return nullptr;
}

void Sample::ModelViewDlg::SetEnabled(bool bEnable)
{
    QDialog::setEnabled(bEnable);
}

void Sample::ModelViewDlg::UpdateStatus()
{
}

void Sample::ModelViewDlg::RemoveImportedObject()
{
    /*/ TODO
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_ui, L"m_ui为空",L"GDMP",L"2023-10-20");
    QTreeWidget* pModelViewTree = m_ui->modelViewTree;
    DBG_WARN_AND_RETURN_VOID_UNLESS(pModelViewTree, L"pModelViewTree为空",L"GDMP",L"2023-10-20");
    QTreeWidgetItem* pCurrentItem = pModelViewTree->currentItem();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pCurrentItem, L"pCurrentItem为空",L"GDMP",L"2023-10-20");
    QFamilyTreeWidgetUtil::RemoveImportedObject(pCurrentItem, ID_CMD_DELETE_CAD_ELEMENT);
    */
}

void Sample::ModelViewDlg::ViewportDeactivate()
{
    DBG_WARN_AND_RETURN_VOID_UNLESS(m_ui, L"m_ui为空",L"GDMP",L"2023-10-20");
    QTreeWidget* pModelViewTree = m_ui->modelViewTree;
    DBG_WARN_AND_RETURN_VOID_UNLESS(pModelViewTree, L"pModelViewTree为空",L"GDMP",L"2023-10-20");
    QTreeWidgetItem* pViewportItem = pModelViewTree->currentItem();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pViewportItem, L"pViewportItem为空",L"GDMP",L"2023-10-20");
    bool isViewportItem = pViewportItem->data(0, PAPER_USER_DATA_ROLE).toString().toStdWString() == L"Drawing Viewport" ? true : false;
    DBG_WARN_AND_RETURN_VOID_UNLESS(isViewportItem, L"viewportItem不是视口的item",L"GDMP",L"2023-10-20");
    QTreeWidgetItem* layoutItem = pViewportItem->parent();
    DBG_WARN_AND_RETURN_VOID_UNLESS(layoutItem, L"视口item对应的图纸item为空",L"GDMP",L"2023-10-20");
    std::wstring layoutName = layoutItem->text(0).toStdWString();

    CommandParameters paramArray;
    paramArray[L"LayoutName"] = layoutName;
    OwnerPtr<gcmp::IJournalCommandData> opJournalCmdData = IJournalCommandData::Create();
    DBG_WARN_AND_RETURN_VOID_UNLESS(opJournalCmdData, L"IJournalCommandData::Create()返回空指针",L"GDMP",L"2023-10-20");
    opJournalCmdData->SetCommandName(ID_CMD_VIEWPORT_ACTIVATED);
    opJournalCmdData->SetParameterArray(paramArray);
    JournalUtils::RecordCommand(TransferOwnership(opJournalCmdData));
    ICommandManager* pCommandManager = ICommandManager::Get();
    DBG_WARN_AND_RETURN_VOID_UNLESS(pCommandManager, L"ICommandManager::Get()返回空指针",L"GDMP",L"2023-10-20");
    pCommandManager->SendCommand(ID_CMD_VIEWPORT_ACTIVATED, paramArray);
}

